package cn.weforward.task.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import cn.weforward.common.NameItem;
import cn.weforward.common.NameItems;
import cn.weforward.common.ResultPage;
import cn.weforward.data.UniteId;
import cn.weforward.data.annotation.Index;
import cn.weforward.data.log.BusinessLog;
import cn.weforward.data.persister.Persister;
import cn.weforward.data.persister.support.AbstractPersistent;
import cn.weforward.framework.ApiException;
import cn.weforward.framework.support.Global;
import cn.weforward.task.Bug;
import cn.weforward.task.Task;
import cn.weforward.task.di.TaskDi;

public class SimpleTask extends AbstractPersistent<TaskDi> implements Task{

	@Resource
	String m_Title;
	@Resource
	String m_Content;
	@Resource
	String m_FatherTaskId;
	@Resource
	int m_Priority;
	@Resource
	int m_State;
	@Resource
	String m_Manager;
	@Resource
	List<String> m_Handlers = new ArrayList<String>();
	@Resource
	List<String> m_Follower = new ArrayList<String>();//第一次新建没有跟进人
	@Resource
	String m_Creator;
	@Index
	@Resource
	String m_Tag;
	@Resource
	Date m_ExpectedStartTime;
	@Resource
	Date m_ExpectedEndTime;
	@Resource
	Date m_CreateTime;
	@Resource
	Date m_EndTime;//第一次新建没有结束时间
	
	/**
	 * 第一次新建任务时，使用这个构造函数
	 * @param di
	 * @param title
	 * @param content
	 * @param fatherTaskId
	 * @param manager
	 * @param handlers
	 * @param tag
	 * @param priority
	 * @param expectedStartTime
	 * @param expectedEndTime
	 */
	protected SimpleTask(TaskDi di,String title,String content,String fatherTaskId,
			String manager,List<String> handlers,String tag
			,int priority,Date expectedStartTime,Date expectedEndTime) {
		super(di);
		genPersistenceId();
		m_Title = title;
		m_Content = content;
		m_FatherTaskId = fatherTaskId;
		m_Priority = priority;
		m_State = Task.STATE_ASSESS.id;
		m_Manager = manager;
		m_Handlers = handlers;
		m_Creator = Global.TLS.getValue("user");
		m_Tag = tag;
		m_ExpectedStartTime = expectedStartTime;
		m_ExpectedEndTime = expectedEndTime;
		m_CreateTime = new Date();
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "新建任务", "新建了标题为 "+title+" 的任务", "无..");
	}
	protected SimpleTask(TaskDi di) {
		super(di);
	}

	@Override
	public NameItem getState() {
		//根据当前id去查询状态
		return STATES.get(m_State);
	}

	@Override
	public UniteId getId() {
		return getPersistenceId();
	}
	
	@Override
	public void setHandlers(List<String> handlers) {
		List<String> oldHandlers = m_Handlers;
		
		if(Arrays.equals(oldHandlers.toArray(new String[] {}), handlers.toArray(new String[] {}))) {
			//如果要设置的处理人和原来的处理人相同
			return;
		}
		
		m_Handlers = handlers;
		
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务处理人", oldHandlers+" 修改为 "+handlers, "无..");
		
	}
	
	@Override
	public void addHandlers(List<String> handlers) {
		List<String> oldHandlers = m_Handlers;
		if(Collections.disjoint(m_Handlers, handlers)) {
			//如果要添加的处理人和已存在的处理人无交集，那么全添加
			m_Handlers.addAll(handlers);
			markPersistenceUpdate();
			getBusinessDi().writeLog(getId(), "修改任务处理人", oldHandlers+" 修改为 "+handlers, "无..");
		}else {
			//如果有交集，先添加，后去重
			m_Handlers.addAll(handlers);
			//去重
		    List<String> result = new ArrayList<String>(m_Handlers.size());
		    for(String handler : m_Handlers) {
		    	if(!result.contains(handler)) {
		    		result.add(handler);
		    	}
		    }
		    m_Handlers.clear();
		    m_Handlers.addAll(result);
		    markPersistenceUpdate();
		    getBusinessDi().writeLog(getId(), "修改任务处理人", oldHandlers+" 修改为 "+handlers, "无..");
		}
//		
//		if(!m_Handlers.containsAll(handlers)) {
//			m_Handlers.addAll(handlers);
//			persistenceUpdateNow();
//		}
	}
	@Override
	public void removeHandlers(List<String> handlers) {
		List<String> oldHandlers = m_Handlers;
		//如果要移除的处理人都包含在内，那么就移除
		if(m_Handlers.containsAll(handlers)) {
			for (int i = 0; i < handlers.size(); i++) {
				m_Handlers.remove(handlers.get(i));
			}
//			m_Handlers.removeAll(handlers);
			
			markPersistenceUpdate();
			getBusinessDi().writeLog(getId(), "修改任务处理人", oldHandlers+" 修改为 "+handlers, "无..");
		}

	}
	
	@Override
	public String getTitle() {
		// TODO Auto-generated method stub
		return m_Title;
	}
	
	@Override
	public void setTitle(String title) {
		String oldTitle = m_Title;
		if(m_Title.equals(title)) {
			return;
		}
			
		m_Title = title;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务标题", oldTitle+" 修改为 "+title, "无..");
	}

	@Override
	public void setContent(String content) {
		String oldContent = m_Content;
		if(m_Content.equals(content)) {
			return;
		}
		m_Content = content;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务内容", oldContent+" 修改为 "+content, "无..");
	}

	@Override
	public void setPriority(int priority) {
		int oldPriority = priority;
		if(m_Priority == priority)
			return;
		if(priority>=1 && priority<=4) {
			m_Priority = priority;
			markPersistenceUpdate();
			getBusinessDi().writeLog(getId(), "修改任务优先级", oldPriority+" 修改为 "+priority, "无..");
		}
	}

	@Override
	public void setManager(String manager) {
		String oldManager = m_Manager;
		if(m_Manager.equals(manager)) {
			return;
		}
		m_Manager = manager;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务负责人", oldManager+" 修改为 "+manager, "无..");
	}

	@Override
	public void addFollower(String follower) {
		if(m_Follower.contains(follower)) {
			return;
		}
		m_Follower.add(follower);
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "添加任务跟进人", "添加了"+follower, "无..");
	}

	@Override
	public void setExpectedStartTime(Date expectedStartTime) {
		Date oldExpectedStartTime = m_ExpectedStartTime;
		if(m_ExpectedStartTime.equals(expectedStartTime)) {
			return;
		}
		m_ExpectedStartTime = expectedStartTime;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务期望开始时间", oldExpectedStartTime+" 修改为 "+expectedStartTime, "无..");
	}

	@Override
	public void setExpectedEndTime(Date expectedEndTime) {
		Date oldExpectedEndTime = m_ExpectedEndTime;
		if(m_ExpectedEndTime.equals(expectedEndTime)) {
			return;
		}
		m_ExpectedEndTime = expectedEndTime;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务期望结束时间", oldExpectedEndTime+" 修改为 "+expectedEndTime, "无..");
	}
	
	@Override
	public void setTag(String tagId) {
		// TODO Auto-generated method stub
		String oldTagId = tagId;
		if(m_Tag.equals(tagId)) {
			return;
		}
		
		m_Tag = tagId;
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "修改任务所属标签", "修改为"+tagId, "无..");
	}
	
	@Override
	public ResultPage<SimpleTask> getSonTasks() {
		// TODO Auto-generated method stub
		return getBusinessDi().getSonTasks(getId().getOrdinal());
	}

//	@Override
//	public void getComments() {
//		// TODO Auto-generated method stub
//		
//	}

	@Override
	public Bug createBug(String content,List<String> handler, String severity, String versionAndPlatForm) {
		// TODO Auto-generated method stub
		Bug bug = getBusinessDi().createBug(content, getId().getOrdinal(), handler, severity, versionAndPlatForm);
		getBusinessDi().writeLog(getId(), "发现了一个bug", "发现了任务标题为 "+getTitle()+" 的任务的一个bug", "无..");
		
		return bug;
	}
	
	@Override
	public ResultPage<SimpleBug> getBugs(String taskId) {
		// TODO Auto-generated method stub
		return getBusinessDi().getAllBugs(getId().getOrdinal());
	}
	@Override
	public void setEndTime(Date endTime) {
		// TODO Auto-generated method stub
		if(m_EndTime == endTime) {
			return;
		}
		
		m_EndTime = endTime;
		
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "任务结束", "结束时间为"+endTime, "无..");
	}
	@Override
	public String getFatherTaskId() {
		return m_FatherTaskId;
	}
	@Override
	public NameItem getPriority() {
		return PRIORITY_STATES.get(m_Priority);
	}
	@Override
	public String getManager() {
		// TODO Auto-generated method stub
		return m_Manager;
	}
	@Override
	public List<String> getHandlers() {
		return m_Handlers;
	}
	@Override
	public List<String> getFollower() {
		return m_Follower;
	}
	@Override
	public String getCreator() {
		// TODO Auto-generated method stub
		return m_Creator;
	}
	@Override
	public String getTag() {
		// TODO Auto-generated method stub
		return m_Tag;
	}
	@Override
	public Date getExpectedStartTime() {
		// TODO Auto-generated method stub
		return m_ExpectedStartTime;
	}
	@Override
	public Date getExpectedEndTime() {
		// TODO Auto-generated method stub
		return m_ExpectedEndTime;
	}
	@Override
	public Date getCreateTime() {
		// TODO Auto-generated method stub
		return m_CreateTime;
	}
	@Override
	public Date getEndTime() {
		// TODO Auto-generated method stub
		return m_EndTime;
	}
	@Override
	public ResultPage<BusinessLog> getLogs() {
		return getBusinessDi().getLogs(getId());
	}
	@Override
	public synchronized void assess() throws ApiException {
		// 如果当前状态为挂起状态，可以扭转为评估中
		if(m_State == STATE_HANGUP.id) {
			changeState(STATE_ASSESS.id);
		}else {
			throwTips(m_State);
		}
	}
	@Override
	public synchronized void plan() throws ApiException {
		// 如果当前状态为评估中，可以扭转为规划中
		if(m_State == STATE_ASSESS.id) {
			changeState(STATE_PLAN.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void gonnaDev() throws ApiException {
		// 如果当前状态为规划中or挂起，可以扭转为待开发
		if(m_State == STATE_PLAN.id || m_State == STATE_HANGUP.id) {
			changeState(STATE_GONNA_DEV.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void dev() throws ApiException {
		// 如果当前状态为待开发or待测试or测试中or测试通过，可以扭转为开发中
		if(m_State == STATE_GONNA_DEV.id || m_State == STATE_GONNA_TEST.id || m_State == STATE_TEST.id || m_State == STATE_PASS_TEST.id) {
			changeState(STATE_DEV.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void gonnaTest() throws ApiException {
		// 如果当前状态为开发中or挂起，可以扭转为待测试
		if(m_State == STATE_DEV.id || m_State == STATE_HANGUP.id) {
			changeState(STATE_GONNA_TEST.id);
		}else {
			throwTips(m_State);
		}
		
	}
	
	@Override
	public synchronized void test() throws ApiException {
		// 如果当前状态为待测试，可以扭转为测试中
		if(m_State == STATE_GONNA_TEST.id) {
			changeState(STATE_TEST.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void passTest() throws ApiException {
		// 如果当前状态为测试中or挂起，可以扭转为测试通过
		if(m_State == STATE_TEST.id || m_State == STATE_PASS_TEST.id) {
			changeState(STATE_PASS_TEST.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void up() throws ApiException {
		// 如果当前状态为测试通过，可以扭转为已上线
		if(m_State == STATE_PASS_TEST.id) {
			changeState(STATE_UP.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void refuse() throws ApiException {
		// 如果当前状态不为已上线and已拒绝，可以扭转为已拒绝
		if(m_State != STATE_UP.id && m_State != STATE_REFUSE.id) {
			changeState(STATE_REFUSE.id);
		}else {
			throwTips(m_State);
		}
		
	}
	@Override
	public synchronized void hangUp() throws ApiException {
		// 如果当前状态不为评估中and已上线and已拒绝and挂起，可以扭转为挂起
		if(m_State != STATE_ASSESS.id && m_State != STATE_UP.id && m_State != STATE_REFUSE.id && m_State != STATE_HANGUP.id) {
			changeState(STATE_HANGUP.id);
		}else {
			throwTips(m_State);
		}
	}
	
	@Override
	public HashMap<String, Integer> analyzeBugs() {
		return getBusinessDi().analyzeBugs(getId().getOrdinal());
	}
	
	/**
	 * 改变状态方法
	 * @param wantState
	 */
	private void changeState(int wantState) {
		int oldState = m_State;
		String oldStateName = STATES.get(oldState).getName();
		m_State = wantState;
		String newStateName = STATES.get(wantState).getName();
		markPersistenceUpdate();
		getBusinessDi().writeLog(getId(), "状态扭转", oldStateName+" 扭转为 "+newStateName, "无..");
	}
	/**
	 * 抛出当前状态能扭转到哪个状态的异常
	 * @param currentState
	 * @throws ApiException
	 */
	private void throwTips(int currentState) throws ApiException {
		//如果当前状态为评估中
		if(currentState == STATE_ASSESS.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"规划中 已拒绝");
		}
		//如果当前状态为规划中
		if(currentState == STATE_PLAN.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"待开发 已拒绝 挂起");
		}
		//如果当前状态为待开发
		if(currentState == STATE_GONNA_DEV.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"开发中 已拒绝 挂起");
		}
		//如果当前状态为开发中
		if(currentState == STATE_DEV.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"待测试 已拒绝 挂起");
		}
		//如果当前状态为待测试
		if(currentState == STATE_GONNA_TEST.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"开发中 测试中 已拒绝 挂起");
		}
		//如果当前状态为测试中
		if(currentState == STATE_TEST.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"开发中 测试通过 已拒绝 挂起");
		}
		//如果当前状态为测试通过
		if(currentState == STATE_PASS_TEST.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"开发中 已上线 已拒绝 挂起");
		}
		//如果当前状态为已上线
		if(currentState == STATE_UP.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 无法扭转到任何状态");
		}
		//如果当前状态为已拒绝
		if(currentState == STATE_REFUSE.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 无法扭转到任何状态");
		}
		//如果当前状态为已挂起
		if(currentState == STATE_HANGUP.id) {
			throw new ApiException(10002, "当前状态为 "+STATES.get(currentState).getName()+" 只能扭转到 "+"评估中 待开发 待测试 测试通过 已拒绝");
		}
	}
	
}
